/**
 * @ Author: luoqi
 * @ Create Time: 2024-11-02 10:16
 * @ Modified by: luoqi
 * @ Modified time: 2025-02-17 20:55
 * @ Description:
 */

#ifndef _QFSM_H
#define _QFSM_H

#include <stdint.h>

typedef struct _fsm_list {
    struct _fsm_list *prev;
    struct _fsm_list *next;
} QFsmList;

typedef struct _qfsm_state {
    const char *name;
    uint32_t id;
    int (*handle)(uint32_t *param);
    uint32_t next_state_id;
    struct _qfsm_state *next_state;
    QFsmList state_node;
} QFsmState;

typedef struct {
    uint32_t *param;
    QFsmState *current_state;
    int (*hook)(uint32_t *param);
    QFsmList state_list;
} QFsm;

#ifndef QNULL
#define QNULL ((void*)0)
#endif

#define QFSM_STATE_CHANGE       0xcc

int qfsm_init(QFsm *fsm, uint32_t *param);

int qfsm_prepare(QFsm *fsm, const char *start_state_name);

/* if function defined, it will be called when state change */
int qfsm_hook_set(QFsm *fsm, int (*hook)(uint32_t *param));

/* if current state handle return  QFSM_STATE_CHANGE, then fsm state change, else state not change */
int qfsm_exec(QFsm *fsm);

int qfsm_state_attach(QFsm *fsm, QFsmState *state, const char *name, const char *next_state_name, int (*handle)(uint32_t *param));

int qfsm_state_detach(QFsm *fsm, QFsmState *state);

int qfsm_state_change(QFsm *fsm, const char *state_name);

#endif
